//战场单位的指令生成

//basic logics
var selectMapStatus = 0;//0：允许选择新单位，1：允许选择新路径/允许点击切换同位置的其它单位，2：只允许选择新路径

var manipulateEnable = false;//为true时可以操作，为false时只能查看信息
var selectedTroop = -1;
var oldTroop = -1;

var directionMenu = {
	selectSymbol : null,
	selectTroopSymbol : null,
	
	//route Menus
	routeMenus : [],
	routeMenuLocation : null,
	
	//strategy Menus
	encounterMenus : [],
	battleMenus : [],
	trivialMenus : [],
	trivialMenuListLocation : [],
	
	Initialize : function(){
		var hDiv = 0.5 * tileEngine.tileHeight;
		var wDiv = 0.5 * tileEngine.tileWidth;
		this.routeMenuLocation = {x : 2 * wDiv, y : 0.75 * hDiv};
		
		this.trivialMenuListLocation = [];
		for (var idx = 0; idx < 10; idx++){
			var xOffset = Math.floor(idx / 2) - 2;
			var yOffset = idx % 2 + 1;
			this.trivialMenuListLocation[idx] = {x : xOffset * 2 * wDiv, y : (-0.75 - yOffset * 1.25) * hDiv};
		}

		this.selectSymbol = new cc.Sprite(resource.selectsymbol_png);
		this.selectSymbol.attr({x: -5000, y: -5000});
		mainMap.node.addChild(this.selectSymbol, 110);
		
		this.selectTroopSymbol = new cc.Sprite(resource.selectsymbol_png);
		this.selectTroopSymbol.attr({x: -5000, y: -5000, color: cc.color(255, 255, 64)});
		this.selectTroopSymbol.runAction(cc.repeatForever(cc.sequence(cc.fadeIn(0.35),cc.delayTime(0.8),cc.fadeOut(0.35))));
		mainMap.node.addChild(this.selectTroopSymbol, 111);
		
		this.routeMenus = [];
		this.routeMenus[0] =	this._CreateBlinkMenu(cc.LabelTTF.create("完毕", "simhei", 28),				0.0, CompleteMenuClick);
		this.routeMenus[1] =	this._CreateBlinkMenu(cc.LabelTTF.create("重设", "simhei", 28),				0.0, ResetMenuClick);
		
		this.encounterMenus = [];
		for (var idx = 0; idx < 2; idx++){
			this.encounterMenus[idx] = this._CreateBlinkMenu(new cc.Sprite(directionInfo.encounterImage[idx]), 0.07, this._EncounterMenuClick);
		}
		
		this.battleMenus = [];
		for (var idx = 0; idx < 2; idx++){
			this.battleMenus[idx] = this._CreateBlinkMenu(new cc.Sprite(directionInfo.battleImage[idx]), 0.14, this._BattleMenuClick);
		}
		
		this.trivialMenus = [];
		for (var idx = 0; idx < 10; idx++){
			this.trivialMenus[idx] = this._CreateBlinkMenu(new cc.Sprite(directionInfo.trivialImage[idx]), 0.21, this._TrivialMenuClick);
		}
		
		var menu = cc.Menu.create(
			this.encounterMenus[0],	this.encounterMenus[1],
			this.battleMenus[0], this.battleMenus[1],
			this.trivialMenus[0], this.trivialMenus[1], this.trivialMenus[2], this.trivialMenus[3], this.trivialMenus[4],
			this.trivialMenus[5], this.trivialMenus[6], this.trivialMenus[7], this.trivialMenus[8], this.trivialMenus[9],
			this.routeMenus[0], this.routeMenus[1]
		);
		menu.attr({x : 0, y : 0});
		mainMap.node.addChild(menu, 112);
	},
	
	//0 <= blinkOffset < 1
	_CreateBlinkMenu : function(symbolNode, blinkOffset, callback){
		var button = new cc.MenuItemImage(resource.troopBtnNormal_png, resource.troopBtnDown_png, resource.troopBtnNormal_png, callback, this);
		button.attr({x: -5000, y: -5000});
		
		symbolNode.attr({x: button.width * 0.5, y: button.height * 0.5});
		button.addChild(symbolNode);
		
		button.runAction(cc.repeatForever(cc.sequence(
			cc.delayTime(blinkOffset),
			cc.fadeOut(0.25),
			cc.fadeIn(0.25),
			cc.delayTime(1.0 - blinkOffset)
		)));
		return button;
	},
	
	_currentRouteMenu : null,
	_currentEncounterMenu : null,
	_currentBattleMenu : null,
	_currentTrivialMenu : null,
	
	SetSelectSymbol : function(coord){
		this.selectSymbol.setPosition(coord.x, coord.y);
	},
	
	HideSelectSymbol : function(){
		this.selectSymbol.setPosition(-5000, -5000);
	},
	
	SetSelectTroopSymbol : function(coord){
		this.selectTroopSymbol.setPosition(coord.x, coord.y);
	},

	HideSelectTroopSymbol : function(){
		this.selectTroopSymbol.setPosition(-5000, -5000);
	},
	
	ShowRouteRange : function(troopid, tileIndex){
		var forceid = campaign.troop[troopid].force;
		var pass_index = ForceInfo.GetTroopPassIndex(forceInfo[forceid], campaign, tileEngine, troopid, false, false);
		var payMap = tileEngine.MapPay(pass_index, tileIndex, 5000);
		var move = campaign.troop[troopid].move;
		for (var tileid = 0; tileid < payMap.length; tileid++){
			var color = cc.color(255,255,255);
			if (payMap[tileid].pay < 0){
				color = cc.color(127,127,127);
			}else if (payMap[tileid].pay <= move){
				color = cc.color(255,223,223);
			}else if (payMap[tileid].pay <= move * 2){
				color = cc.color(255,255,127);
			}else if (payMap[tileid].pay <= move * 3){
				color = cc.color(223,223,255);
			}else if (payMap[tileid].pay <= move * 4){
				color = cc.color(191,255,191);
			}
			terrain.terrainblankSprites[tileid].setColor(color);
			terrain.terrainSprites[tileid].setColor(color);
		}
	},
	
	HideRouteRange : function(){
		var color = cc.color(255,255,255);
		for (var tileid = 0; tileid < tileEngine.tileCount; tileid++){
			terrain.terrainblankSprites[tileid].setColor(color);
			terrain.terrainSprites[tileid].setColor(color);
		}
	},
	
	SwitchRouteMenu : function(tileIndex, isCompleteMenu){
		var showid = isCompleteMenu ? 0 : 1;
		var hideid = 1 - showid;
		var coord = tileEngine.IndexToCoord(tileIndex);
		this.routeMenus[hideid].setPosition(-5000, -5000);
		this.routeMenus[showid].setPosition(coord.x + this.routeMenuLocation.x, coord.y + this.routeMenuLocation.y);
	},
	
	HideRouteMenu : function(){
		this.routeMenus[0].setPosition(-5000, -5000);
		this.routeMenus[1].setPosition(-5000, -5000);
	},
	
	ShowStrategyMenu : function(troopid){
		this.HideStrategyMenu();
		var coord = {x:warTroop.troopHolders[troopid].x, y:warTroop.troopHolders[troopid].y};
		this.encounterMenus[direction[troopid].encounter].setPosition(coord.x + directionInfo.unfoldLocation[0].x, coord.y + directionInfo.unfoldLocation[0].y);
		this.battleMenus[direction[troopid].battle].setPosition(coord.x + directionInfo.unfoldLocation[1].x, coord.y + directionInfo.unfoldLocation[1].y);
		var trivialID = direction[troopid].trivial * 2 + direction[troopid].trivialMeantime;
		this.trivialMenus[trivialID].setPosition(coord.x + directionInfo.unfoldLocation[2].x, coord.y + directionInfo.unfoldLocation[2].y);
		
		this.trivialMenuListing = false;
	},
	
	HideStrategyMenu : function(){
		for (var idx = 0; idx < this.trivialMenus.length; idx++){
			if (idx < 2){
				this.encounterMenus[idx].setPosition(-5000, -5000);
				this.battleMenus[idx].setPosition(-5000, -5000);
			}
			this.trivialMenus[idx].setPosition(-5000, -5000);
		}
		this.trivialMenuListing = true;
	},
	
	SetAllMenuEnable : function(enable){
		for (var idx = 0; idx < this.trivialMenus.length; idx++){
			if (idx < 2){
				this.encounterMenus[idx].enabled = enable;
				this.battleMenus[idx].enabled = enable;
			}
			this.trivialMenus[idx].enabled = enable;
		}
	},
	
	_EncounterMenuClick : function(sender){
		hideid = direction[selectedTroop].encounter;
		direction[selectedTroop].encounter = 1 - direction[selectedTroop].encounter;
		showid = direction[selectedTroop].encounter;
		
		var coord = tileEngine.IndexToCoord(campaign.troop[selectedTroop].tileIndex);
		this.encounterMenus[hideid].setPosition(-5000, -5000);
		this.encounterMenus[showid].setPosition(coord.x + directionInfo.unfoldLocation[0].x, coord.y + directionInfo.unfoldLocation[0].y);
		
		var tip = "";
		if (direction[selectedTroop].encounter == 0){
			tip = "行军策略 - 攻势穿插：行军途中只攻击行军路径上的敌军部队";
		}else{
			tip = "行军策略 - 步步为营：行军途中遇到任何敌军部队时，暂停行军并执行交战策略";
		}
		tipPanel.ShowTip(tip);
	},
	
	_BattleMenuClick : function(sender){
		hideid = direction[selectedTroop].battle;
		direction[selectedTroop].battle = 1 - direction[selectedTroop].battle;
		showid = direction[selectedTroop].battle;

		var coord = tileEngine.IndexToCoord(campaign.troop[selectedTroop].tileIndex);
		this.battleMenus[hideid].setPosition(-5000, -5000);
		this.battleMenus[showid].setPosition(coord.x + directionInfo.unfoldLocation[1].x, coord.y + directionInfo.unfoldLocation[1].y);
		
		var tip = "";
		if (direction[selectedTroop].battle == 0){
			tip = "交战策略 - 主动出击：交战时，主动攻击周围价值最高的敌军部队";
		}else{
			tip = "交战策略 - 被动固守：交战时，被动固守，不主动攻击";
		}
		tipPanel.ShowTip(tip);
	},
	
	trivialMenuListing : true,
	
	_TrivialMenuClick : function(sender){
		if (this.trivialMenuListing){
			var trivial = Math.floor((sender.zIndex - 4) / 2);
			var trivialMeantime = (sender.zIndex - 4) % 2;
			direction[selectedTroop].trivialMeantime = trivialMeantime;
			direction[selectedTroop].trivial = trivial;
			
			directionInfo.ClearTroopDirection(selectedTroop);
			this.ShowStrategyMenu(selectedTroop);
			
			var tip = "";
			if (trivial == 0 && trivialMeantime == 0){
				tip = "常务策略 - 目的地破交：到达目的地后，破坏该地交通（设障、炸桥、布雷等）";
			}else if (trivial == 0 && trivialMeantime == 1){
				tip = "常务策略 - 沿线破交：行军的同时，破坏沿线交通（设障、炸桥、布雷等）";
			}else if (trivial == 1 && trivialMeantime == 0){
				tip = "常务策略 - 目的地筑交：到达目的地后，修善该地交通（铺路、架桥、排雷等）";
			}else if (trivial == 1 && trivialMeantime == 1){
				tip = "常务策略 - 沿线筑交：行军的同时，修善沿线交通（铺路、架桥、排雷等）";
			}else if (trivial == 2 && trivialMeantime == 0){
				tip = "常务策略 - 目的地破防：到达目的地后，破坏该地防御工事";
			}else if (trivial == 2 && trivialMeantime == 1){
				tip = "常务策略 - 沿线破防：行军的同时，破坏沿线防御工事";
			}else if (trivial == 3 && trivialMeantime == 0){
				tip = "常务策略 - 目的地筑防：到达目的地后，修筑防御工事";
			}else if (trivial == 3 && trivialMeantime == 1){
				tip = "常务策略 - 沿线筑防：行军的同时，修筑沿线防御工事";
			}else if (trivial == 4 && trivialMeantime == 0){
				tip = "常务策略 - 目的地休整：到达目的地后，进行部队休整";
			}else if (trivial == 4 && trivialMeantime == 1){
				tip = "常务策略 - 沿线休整：行军的同时，进行部队休整";
			}
			tipPanel.ShowTip(tip);
		}else{
			this.HideStrategyMenu();
			directionInfo.AddTroopDirection(selectedTroop, direction[selectedTroop], false);
			
			var coord = tileEngine.IndexToCoord(campaign.troop[selectedTroop].tileIndex);
			for (var idx = 0; idx < 10; idx++){
				this.trivialMenus[idx].setPosition(
					coord.x + this.trivialMenuListLocation[idx].x,
					coord.y + this.trivialMenuListLocation[idx].y);
			}
		}
	},
	
	_showDirectionMenuTimeoutHandle : null,
	
	_troopid : -1,
	
	ShowDirectionMenu : function(troopid){
		this._troopid = troopid;
		directionInfo.FoldTroopDirection(troopid, false);
		directionMenu._showDirectionMenuTimeoutHandle = setTimeout(
				directionMenu._ShowDirectionMenu, directionInfo.foldDuration * 1000);
	},
	
	StopShowDirectionMenu : function(){
		if (directionMenu._showDirectionMenuTimeoutHandle != null){
			clearTimeout(directionMenu._showDirectionMenuTimeoutHandle);
			directionMenu._showDirectionMenuTimeoutHandle = null;
		}
	},
	
	_ShowDirectionMenu : function(){
		directionInfo.ClearTroopDirection(directionMenu._troopid);
		directionMenu.ShowStrategyMenu(directionMenu._troopid);
	},

	HideDirectionMenu : function(troopid){
		this.StopShowDirectionMenu();
		this.HideStrategyMenu();
		directionInfo.AddTroopDirection(oldTroop, direction[oldTroop], false);
		directionInfo.FoldTroopDirection(oldTroop, true);
	},
};

//Unload on Old Step
var UnLoadDirections = function(){
	directionMenu.HideSelectSymbol();
	directionMenu.HideSelectTroopSymbol();
	directionMenu.HideRouteRange();
	directionMenu.HideRouteMenu();
	directionMenu.HideStrategyMenu();
	
	courtDirectionMenu.HideSelectTroopSymbol();
	courtDirectionMenu.HideRouteMenu();
	
	courtPanel.HideUI();
	
	for (var troopid in campaign.troop){
		directionInfo.ClearTroopRoute(troopid);
		directionInfo.ClearTroopDirection(troopid);
	}
};

//Load on New Step
var LoadDirections = function(){
	for (var troopid in campaign.troop){
		if (campaign.troop[troopid].strength <= 0) continue;

		if (campaign.troop[troopid].force != showingForce)
			continue;

		if (direction[troopid].routeTiles.length > 1){
			if (campaign.troop[troopid].court_force){
				directionInfo.DrawTroopCourtRoute(troopid, direction[troopid].routeTiles, direction[troopid].attackIdxOfRoute);
			}else{
				directionInfo.DrawTroopRoute(troopid, direction[troopid].routeTiles, direction[troopid].attackIdxOfRoute);
			}
		}			

		directionInfo.AddTroopDirection(troopid, direction[troopid], true);
	}
	
	courtPanel.ShowUI();

	selectedTroop = -1;
	oldTroop = -1;
	selectMapStatus = 0;
};

var CompleteMenuClick = function(sender){
	direction[selectedTroop].arranged = true;
	selectMapStatus = 0;
	if (campaign.troop[selectedTroop].court_force){
		directionMenu.HideRouteMenu();
		courtDirectionMenu.SwitchRouteMenu(campaign.troop[selectedTroop].tileIndex, false);
	}else{
		courtDirectionMenu.HideRouteMenu();
		directionMenu.SwitchRouteMenu(campaign.troop[selectedTroop].tileIndex, false);
	}

	directionMenu.HideSelectSymbol();

	var tip = "\"目标位置\"已确认，可点击\"重设\"进行重新设置";
	tipPanel.ShowTip(tip);
};

var ResetMenuClick = function(sender){
	direction[selectedTroop].arranged = false;
	selectMapStatus = 1;
	direction[selectedTroop].routeTiles = [campaign.troop[selectedTroop].tileIndex];
	direction[selectedTroop].attackIdxOfRoute = [0];
	direction[selectedTroop].atRoute = 0;
	direction[selectedTroop].moveAlready = 0;
	direction[selectedTroop].marchStatus = 0;
	directionInfo.ClearTroopRoute(selectedTroop);
	if (campaign.troop[selectedTroop].court_force){
		directionMenu.HideRouteMenu();
		courtDirectionMenu.SwitchRouteMenu(campaign.troop[selectedTroop].tileIndex, true);
	}else{
		courtDirectionMenu.HideRouteMenu();
		directionMenu.SwitchRouteMenu(campaign.troop[selectedTroop].tileIndex, true);
	}

	var tip = "已清除\"目标位置\"，请点击地图进行设置，并点击\"完毕\"进行确认";
	tipPanel.ShowTip(tip);
};

onBattleLayerClicked[0] = function(touch, event){
	var winloc = touch.getLocation();

	var location = mainMap.LayerToNodeCoord(winloc);
	var tile = tileEngine.tileNet.CoordToTile(location);
	var isMainMap = tileEngine.TileInBox(tile);
	
	var location_CourtPanel = courtPanel.LayerToNodeCoord(winloc);
	var isCourtPanel = courtPanel.CoordInBox(location_CourtPanel);
	
	var isSameTroopTile = false;
	if (isMainMap && !isCourtPanel){
		var tileIndex = tileEngine.TileToIndex(tile);
		directionMenu.SetSelectSymbol(tileEngine.IndexToCoord(tileIndex));
		tipPanel.ShowTileParam(showingForce, tileIndex);
		
		if (selectedTroop >= 0){
			isSameTroopTile = tileIndex == campaign.troop[selectedTroop].tileIndex;
		}
	}
	
	if (isCourtPanel || selectMapStatus == 0 || (selectMapStatus == 1 && isSameTroopTile)){
		//选择新单位状态
		if (isCourtPanel){
			OnCourtPanelSelectTroop(location_CourtPanel);
		}else if (isMainMap){
			OnMainMapSelectTroop(location);
		}
	}else{
		//以下为允许命令发布
		if (manipulateEnable == false)
			return;
		
		//选择新目标点状态
		if (isMainMap == false)
			return;
		
		if (campaign.troop[selectedTroop].court_force){
			OnMainMapSelectCourtRoute(location);
		}else{
			OnMainMapSelectRoute(location);
		}
	}
};

var OnMainMapSelectTroop = function(location){
	var tileIndex = tileEngine.CoordToIndex(location);
	
	var isSameTroopTile = selectedTroop != -1 && tileIndex == campaign.troop[selectedTroop].tileIndex;
	var foundTroop = warTroop.GetTileTroop(tileIndex, isSameTroopTile);
	if (foundTroop != -1){
		var forceid = showingForce;
		if (forceInfo[forceid].seeMap[tileIndex] == false){
			//选中不可见区域
			return;
		}
		
		tipPanel.ShowTroopParam(foundTroop);

		if (campaign.troop[foundTroop].force != forceid){
			//选中敌对单位
			return;
		}
		courtDirectionMenu.HideSelectTroopSymbol();
		courtDirectionMenu.HideRouteMenu();
		
		directionMenu.HideSelectSymbol();
		directionInfo.BlinkTroopRoute(foundTroop);
		if (foundTroop == selectedTroop){
			//再次选中已选单位
			return;
		}
		
		//选中新单位
		oldTroop = selectedTroop;
		selectedTroop = foundTroop;

		directionMenu.ShowRouteRange(selectedTroop, tileIndex);

		var troopCoord = {x:warTroop.troopHolders[selectedTroop].x,y:warTroop.troopHolders[selectedTroop].y};
		courtDirectionMenu.HideSelectTroopSymbol();
		directionMenu.SetSelectTroopSymbol(troopCoord);
		
		//播放standby音效
		effectEngine.PlayOnNext(campaign.troop[selectedTroop].standby_effect, false, 1);

		if (oldTroop >= 0 && campaign.troop[oldTroop].court_force == false){
			directionMenu.HideDirectionMenu(oldTroop);
		}
		
		//以下为允许命令发布
		if (manipulateEnable == false)
			return;
		
		directionMenu.ShowDirectionMenu(selectedTroop);

		if (direction[selectedTroop].arranged){//已有了安排，则可以重设
			selectMapStatus = 0;
			directionMenu.SwitchRouteMenu(tileIndex, false);
		}else{
			//无安排，则必须安排
			selectMapStatus = 1;
			directionMenu.SwitchRouteMenu(tileIndex, true);
		}
	}else{
		//选中地形
	}
};

var OnMainMapSelectRoute = function(location){
	//选择新的路径点
	var tileIndex = tileEngine.CoordToIndex(location);
	var coord = tileEngine.IndexToCoord(tileIndex);

	directionMenu.SetSelectSymbol(coord);

	var tgtRouteTiles = direction[selectedTroop].routeTiles;

	if (tgtRouteTiles[tgtRouteTiles.length - 1] == tileIndex){
		//选中的路径点即当前路径点
	}else{
		//计算路径
		var startindex = tgtRouteTiles[tgtRouteTiles.length - 1];
		var endindex = tileIndex;
		var forceid = campaign.troop[selectedTroop].force;
		var accessable = AppendRouteTiles(
				tgtRouteTiles,
				ForceInfo.GetTroopPassIndex(forceInfo[forceid], campaign, tileEngine, selectedTroop, false, false),
				startindex,
				endindex);
		
		if (accessable){
			selectMapStatus = 2;
			//设置按钮位置
			directionMenu.SwitchRouteMenu(tileIndex, true);

			//赋给目标指令(routeTiles中的第几个tile为目标)
			direction[selectedTroop].attackIdxOfRoute[direction[selectedTroop].attackIdxOfRoute.length] = tgtRouteTiles.length - 1;

			//绘制进军路径
			if (direction[selectedTroop].routeTiles.length > 1){
				directionInfo.DrawTroopRoute(selectedTroop, direction[selectedTroop].routeTiles, direction[selectedTroop].attackIdxOfRoute);
			}
		}
	}
};

var AppendRouteTiles = function(tgtRouteTiles, pass_index, startindex, endindex){
	tgtRouteTiles = tgtRouteTiles || [startindex];

	var score = tileEngine.RoutePay(pass_index, tgtRouteTiles[tgtRouteTiles.length - 1], endindex, true);
	if (score.pay < 0)
		return false;
	
	var routetileIndex = tgtRouteTiles.length;
	for (var idx = score.route.length - 2; idx > -1; idx--){
		tgtRouteTiles[routetileIndex++] = score.route[idx];
	}
	return true;
};

control.onDebugClick = function(sender){
	cc.log("selected troopid:  " + selectedTroop);
	if (selectedTroop > -1){
		cc.log("selected troop:\n" + JSON.stringify(campaign.troop[selectedTroop]));
		cc.log("selected direction:\n" + JSON.stringify(direction[selectedTroop]));
	}
	cc.log("last 2 step processes:");
	for (var idx = 2; idx > 0; idx--){
		var step = campaign.time_ref.current_step - idx;
		if (wholeProcess[step] != null){
			cc.log("   process step:" + step);
			for (var processid = 0; processid < wholeProcess[step].length; processid++)
				cc.log("      " +  JSON.stringify(wholeProcess[step][processid]));
		}
	}
	cc.log("forceInfs:");
	for (var idx = 0; idx < forceInfo.length; idx++){
		cc.log(JSON.stringify(forceInfo[idx]));
	}
};